package com.mall.server.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.mall.server.model.VerificationCode;
import com.mall.server.repository.VerificationCodeRepository;
import com.mall.server.service.VerificationCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

@Service
public class VerificationCodeServiceImpl implements VerificationCodeService {
    
    private static final Logger logger = Logger.getLogger(VerificationCodeServiceImpl.class.getName());
    
    // 验证码存储
    private List<VerificationCode> codeList = new ArrayList<>();
    private Map<String, VerificationCode> codeMap = new HashMap<>();
    
    @Autowired
    private VerificationCodeRepository verificationCodeRepository;
    
    private final Random random = new Random();
    private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
    
    @PostConstruct
    public void init() {
        try {
            // 从JSON文件加载验证码数据
            ClassPathResource resource = new ClassPathResource("data/verification_codes.json");
            codeList = objectMapper.readValue(resource.getInputStream(), new TypeReference<List<VerificationCode>>() {});
            
            logger.info("从JSON文件加载了 " + codeList.size() + " 个验证码");
            
            // 将验证码添加到映射中，以便按手机号快速查找
            for (VerificationCode code : codeList) {
                // 只保留未过期且未使用的验证码
                if (!code.isExpired() && !code.isUsed()) {
                    codeMap.put(code.getPhone(), code);
                }
            }
            
            // 清理过期或已使用的验证码
            codeList.removeIf(code -> code.isExpired() || code.isUsed());
            saveVerificationCodesToJson();
            
            logger.info("验证码数据初始化完成");
        } catch (IOException e) {
            logger.log(Level.SEVERE, "加载验证码数据时出错", e);
            // 如果加载失败，使用空列表
            codeList = new ArrayList<>();
        }
    }
    
    // 保存验证码数据到JSON文件
    private void saveVerificationCodesToJson() {
        try {
            String filePath = new ClassPathResource("data").getFile().getAbsolutePath() + "/verification_codes.json";
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(filePath), codeList);
            logger.info("验证码数据已保存到JSON文件");
        } catch (IOException e) {
            logger.log(Level.SEVERE, "保存验证码数据时出错", e);
        }
    }
    
    @Override
    public String generateCode(String phone) {
        logger.info("为手机号生成验证码: " + phone);
        
        // 生成6位数字验证码
        String code = String.format("%06d", random.nextInt(1000000));
        
        // 设置验证码有效期为5分钟
        LocalDateTime expiryTime = LocalDateTime.now().plusMinutes(5);
        
        // 创建验证码记录
        VerificationCode verificationCode = new VerificationCode();
        verificationCode.setPhone(phone);
        verificationCode.setCode(code);
        verificationCode.setExpiryTime(expiryTime);
        verificationCode.setUsed(false);
        
        // 保存到内存和JSON文件
        codeMap.put(phone, verificationCode);
        
        // 添加到列表前，移除该手机号的旧验证码
        codeList.removeIf(c -> c.getPhone().equals(phone));
        codeList.add(verificationCode);
        
        // 保存到JSON文件
        saveVerificationCodesToJson();
        
        logger.info("验证码生成成功: " + phone + " -> " + code);
        
        // 在实际应用中，这里应该调用短信服务发送验证码
        // 为测试方便，直接返回生成的验证码
        return code;
    }
    
    @Override
    public boolean verifyCode(String phone, String code) {
        logger.info("验证手机号的验证码: " + phone + ", 验证码: " + code);
        
        // 如果code为null或不是6位数字，直接返回false
        if (code == null || !code.matches("\\d{6}")) {
            logger.warning("验证码格式无效: " + code);
            return false;
        }
        
        // 从映射中获取验证码记录
        VerificationCode verificationCode = codeMap.get(phone);
        
        if (verificationCode == null) {
            logger.warning("没有找到手机号对应的验证码记录: " + phone);
            return false;
        }
        
        // 检查验证码是否已使用或过期
        if (verificationCode.isUsed()) {
            logger.warning("验证码已使用: " + phone);
            return false;
        }
        
        if (verificationCode.isExpired()) {
            logger.warning("验证码已过期: " + phone);
            return false;
        }
        
        // 检查验证码是否匹配
        boolean isValid = verificationCode.getCode().equals(code);
        
        if (isValid) {
            // 验证成功后标记为已使用
            verificationCode.setUsed(true);
            
            // 更新列表和JSON文件
            for (int i = 0; i < codeList.size(); i++) {
                if (codeList.get(i).getPhone().equals(phone)) {
                    codeList.set(i, verificationCode);
                    break;
                }
            }
            saveVerificationCodesToJson();
            
            logger.info("验证码验证成功: " + phone);
        } else {
            logger.warning("验证码不匹配: " + phone + ", 预期: " + verificationCode.getCode() + ", 实际: " + code);
        }
        
        return isValid;
    }
} 